package com.stars.easyms.datasource.enums;

import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 数据库类型
 *
 * @author guoguifang
 * @date 2018-10-19 10:07
 * @since 1.0.0
 */
public enum DatabaseType {

    /**
     * ORACLE
     */
    ORACLE("oracle", "oracle", "oracle.jdbc.OracleDriver", "jdbc:oracle:thin:@", ":", null, "SELECT 1 FROM DUAL"),

    /**
     * MYSQL
     */
    MYSQL("mysql", "mysql", "com.mysql.jdbc.Driver", "jdbc:mysql://", "/",
            "useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true&useSSL=false", "SELECT 1"),

    /**
     * SQLSERVER 2000
     */
    SQLSERVER_2000("sqlserver_2000", "sqlserver", "com.microsoft.jdbc.sqlserver.SQLServerDriver", "jdbc:microsoft:sqlserver://", ";DatabaseName=", null, "select 1"),

    /**
     * SQLSERVER 2005
     */
    SQLSERVER_2005("sqlserver_2005", "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://", ";DatabaseName=", null, "select 1"),

    /**
     * DB2
     */
    DB2("db2", "db2", "com.ibm.db2.jcc.DB2Driver", "jdbc:db2://", "/", null, "select 1 from sysibm.sysdummy1"),

    /**
     * PostgreSQL
     */
    POSTGRESQL("postgresql", "postgresql", "org.postgresql.Driver", "jdbc:postgresql://", "/", null, "select version()");

    private String code;

    private String dbType;

    private String driverClassName;

    private String connectPrefix;

    private String connectSuffix;

    private String defaultConnectParams;

    private String defaultValidationQuery;

    private static Map<String, DatabaseType> codeLookup;

    public static DatabaseType forCode(String code) {
        if (StringUtils.isBlank(code)) {
            return null;
        }
        return codeLookup.get(code);
    }

    public static DatabaseType forUrlOrDriverClassName(String value) {
        if (StringUtils.isNotBlank(value)) {
            if (value.startsWith("jdbc:microsoft:") || value.startsWith("com.microsoft.jdbc.sqlserver")) {
                return SQLSERVER_2000;
            }
            if (value.startsWith("jdbc:sqlserver:") || value.startsWith("com.microsoft.sqlserver.jdbc")) {
                return SQLSERVER_2005;
            }
            for (DatabaseType databaseType : values()) {
                if (value.contains(databaseType.dbType)) {
                    return databaseType;
                }
            }
        }
        return null;
    }

    DatabaseType(String code, String dbType, String driverClassName, String connectPrefix, String connectSuffix, String defaultConnectParams, String defaultValidationQuery) {
        this.code = code;
        this.dbType = dbType;
        this.driverClassName = driverClassName;
        this.connectPrefix = connectPrefix;
        this.connectSuffix = connectSuffix;
        this.defaultConnectParams = defaultConnectParams;
        this.defaultValidationQuery = defaultValidationQuery;
    }

    static {
        codeLookup = new HashMap<>();
        for (DatabaseType databaseType : values()) {
            codeLookup.put(databaseType.code, databaseType);
        }
    }

    public String getCode() {
        return code;
    }

    public String getDbType() {
        return dbType;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public String getConnectPrefix() {
        return connectPrefix;
    }

    public String getConnectSuffix() {
        return connectSuffix;
    }

    public String getDefaultConnectParams() {
        return defaultConnectParams;
    }

    public String getDefaultValidationQuery() {
        return defaultValidationQuery;
    }
}
